package cn.dipper;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

/** 
* @ClassName: Processor 
* @Description: 处理请求的核心类
* @author zx zx2009428@163.com
* @date 2014年12月22日 下午3:52:31 
*  
*/
public class Processor extends Thread{
	//socket对象
	private Socket socket;
	//请求的输入流
	private InputStream inputStream;
	//输出流
	private PrintStream print;
	
	//只能访问特定目录下的文件
	private final static String WEB_ROOT = "E:\\webserver\\webapp\\www"; 
	
	public  Processor(Socket socket){
		this.socket 	 = socket;
		try {
			//获取输入流
			this.inputStream = socket.getInputStream();
			this.print       = new PrintStream(socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	/* (启动线程) 
	* <p>Title: run</p> 
	* <p>Description: </p>  
	* @see java.lang.Thread#run() 
	*/
	public void run(){
		//获得用户访问的文件名（访问协议在输入流里）
		String filename = parse(inputStream);
		this.sendFile(filename);
	}


	//
	/** 
	* @Title: parse 
	* @Description: 根据输入流得到要访问的方法，返回资源名称（文件名）
	* @param     设定文件 
	* @return String    返回类型 
	* @throws 
	*/
	public String parse(InputStream in){
		//处理http协议
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		String filename  ="";
		try {
			//获得协议第一行的信息
			String httpMessage = br.readLine();
			
			if(httpMessage==null){
				return null;
			}
			//http协议第一行分三个部分，用空格隔开的
			//part1 协议的状态方法
			//part2请求文件的名称
			//part3协议的版本号
			System.out.println(httpMessage);
			String[] context =  httpMessage.split(" ");
			
			if(context.length!=3){
				this.sendErrorMessage(400, "Client query error! 客户请求错误！");
				return null;
			}
			System.out.println("method:"+context[0]);
			System.out.println("filename:"+context[1]);
			System.out.println("http version:"+context[2]);
			filename=context[1];
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return filename;
	}
	

	/** 
	* @Title: sendErrorMessage 
	* @Description: 出错时根据错误编号和错误信息处理错误
	* @param @param errorcode
	* @param @param errorMessage    设定文件 
	* @return void    返回类型 
	* @throws 
	*/
	public void sendErrorMessage(int errorcode,String errorMessage){
		print.println("HTTP/1.1 "+errorcode+" "+errorMessage);
		print.println("content-type: text/html");
		print.println();
		print.println("<html>");
		print.println("<head>");
		print.println("<title>ERROR Message");
		print.println("</title>");
		print.println("</head>");
		print.println("<body>");
		print.println("<body>");
		
		print.println("<h1 style='color:red;'>ERRORCode:"+errorcode+"<br>Message"+errorMessage+"</h1>");
		
		print.println("</body>");
		print.println("</html>");
		print.flush();
		print.close();
		try {
			inputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	/** 
	* @Title: sendFile 
	* @Description: 请求正确时返回访问的资源
	* @param @param fileName    设定文件 
	* @return void    返回类型 
	* @throws 
	*/
	public void sendFile(String fileName){
		
		File file = new File(Processor.WEB_ROOT+fileName);
		//如果文件不存在
		if(!file.exists()){
			this.sendErrorMessage(404, "File Not Found!所访问的文件没找到");
			return ;
		}
		
		try {
			
			//如果能找到文件读取文件
			InputStream in = new FileInputStream(file);
			//声明一个与文件内容长度一样的字节数组
			byte content[] = new byte[(int)file.length()];
			//将内容读取到字节数组里
			in.read(content);
			
			//响应协议信息 版本号和动作
			print.println("HTTP/1.1 200 queryfile");
			
			//响应头部信息 相应内容长度
			print.println("content-length:"+content.length);
			print.println();
			//响应内容
			print.write(content);
			print.flush();
			//关闭输出流
			print.close();
			//关闭输入流
			inputStream.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
	
}
